#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
IR 导入节点定义
"""

import ast
import copy

from dataclasses import dataclass, field
from typing import TYPE_CHECKING, List, Optional, Iterator, Dict
from enum import Enum, auto

from ..base import IRNode

from ...symbol_table import Symbol
from ...symbol_meta import SymbolKind, TypeInfo, TypeKind
from ..module import IRModule
from mcpy.symbol_registry import get_global_registry

if TYPE_CHECKING:
    from ...compiler import MCPyCompiler
    from ...symbol_meta import Signature


filter_modules = ["typing", "mcpy.decorators"]


class ImportKind(Enum):
    """Import类型"""

    IMPORT = auto()  # import module
    FROM_IMPORT = auto()  # from module import symbol


@dataclass
class IRImportNode(IRNode):
    """IR导入语句节点"""

    node_type: str = "import"

    name: str = field(default="")
    source_line: int = field(default=0)
    import_type: str = field(default="include")  # "include", "forward_decl"

    # 导入的符号和模块
    imported_symbols: List[str] = field(default_factory=list)  # for FROM_IMPORT
    imported_modules: List[str] = field(default_factory=list)  # for IMPORT
    import_kind: ImportKind = field(default=ImportKind.FROM_IMPORT)

    # 对于 FROM_IMPORT，存储源模块路径
    source_module: str = field(default="")  # from {source_module} import ...

    # 解析后的模块引用（可能有多个）
    resolved_modules: Dict[str, "IRModule"] = field(default_factory=dict)

    # 解析状态
    is_resolved: bool = field(default=False)

    def get_local_symbols(self) -> Iterator[Symbol]:
        """获取导入的局部符号

        重要：只有 import 后，模块才作为符号进入当前作用域
        """
        ir_module = self.get_ir_module()
        if not ir_module:
            return

        if self.import_kind == ImportKind.IMPORT:
            # import module1, module2, module3
            for module_name, resolved_module in self.resolved_modules.items():
                module_symbol = Symbol(
                    name=module_name,
                    kind=SymbolKind.MODULE,
                    ir_node=self,
                    type_info=TypeInfo(kind=TypeKind.MODULE, name=module_name),
                )
                yield module_symbol

        elif self.import_kind == ImportKind.FROM_IMPORT:
            # from module import symbol1, symbol2
            source_ir_module = self.resolved_modules.get(self.source_module)
            if not source_ir_module:
                return

            for symbol_name in self.imported_symbols:
                imported_symbol = self._lookup_imported_symbol(
                    symbol_name, source_ir_module
                )

                # 如果是子模块，跳过（子模块的符号已经在 _import_symbols_from_module 中注册）
                if imported_symbol is None:
                    continue

                new_symbol = self._create_imported_symbol(
                    imported_symbol, symbol_name, ir_module, source_ir_module
                )
                self._copy_signatures_to_symbol(
                    new_symbol, symbol_name, ir_module, source_ir_module
                )

                yield new_symbol

    def _lookup_imported_symbol(
        self, symbol_name: str, ir_module: "IRModule"
    ) -> Optional[Symbol]:
        """查找导入的符号（先查找类型，再查找函数）

        Returns:
            Symbol: 符号对象，如果是子模块则返回 None
        """
        imported_symbol = ir_module.lookup_symbol(
            symbol_name, symbol_kinds=[SymbolKind.CLASS]
        )
        if not imported_symbol:
            imported_symbol = ir_module.lookup_symbol(symbol_name)

        if not imported_symbol:
            # 可能是子模块，尝试检测
            if self._is_submodule(symbol_name, ir_module):
                return None
            raise ValueError(
                f"模块 {ir_module.module_full_name} 中符号 {symbol_name} 不存在"
            )

        return imported_symbol

    def _is_submodule(self, name: str, ir_module: "IRModule") -> bool:
        """检查名称是否是子模块

        Args:
            name: 名称
            ir_module: 父模块

        Returns:
            bool: 是否是子模块
        """
        # 构建子模块的完整路径
        parent_module_path = ir_module.module_full_name
        submodule_path = f"{parent_module_path}.{name}"

        # 获取编译器
        compiler = self._get_compiler()
        if not compiler:
            return False

        module_manager = compiler.get_module_manager()

        # 尝试查找子模块
        submodule = module_manager.get_module(submodule_path)
        return submodule is not None

    def _create_imported_symbol(
        self,
        imported_symbol: Symbol,
        symbol_name: str,
        ir_module: "IRModule",
        source_ir_module: "IRModule",
    ) -> Symbol:
        """创建导入符号的副本"""
        return Symbol(
            name=symbol_name,
            kind=imported_symbol.kind,
            type_info=imported_symbol.type_info,
            module=ir_module.module_full_name,
            line=self.source_line,
            column=imported_symbol.column,
            is_imported=True,
            import_path=source_ir_module.module_full_name,
            ir_node=imported_symbol.ir_node,
            scope_node=imported_symbol.scope_node,
            is_static=imported_symbol.is_static,
            type_config=imported_symbol.type_config,
            priority=imported_symbol.priority,
            is_template_type=imported_symbol.is_template_type,
            is_type_alias=imported_symbol.is_type_alias,
            canonical_name=imported_symbol.canonical_name,
        )

    def _copy_signatures_to_symbol(
        self,
        new_symbol: Symbol,
        symbol_name: str,
        ir_module: "IRModule",
        source_ir_module: "IRModule",
    ) -> None:
        """从导入符号复制签名

        直接从源模块的符号复制signatures，确保保留所有信息（如template_params）
        同时应用命名空间前缀到emit_template
        """
        import copy

        # 从源模块获取导入的符号
        imported_symbol = source_ir_module.lookup_symbol(symbol_name)
        if imported_symbol and imported_symbol.signatures:
            # 获取源模块的命名空间
            namespace = source_ir_module.get_extension_param("namespace")

            # 复制并处理每个签名
            for sig in imported_symbol.signatures:
                # 深拷贝签名以避免修改原始签名
                new_sig = copy.deepcopy(sig)

                # 如果源模块有命名空间，添加到emit_template
                if namespace and not new_sig.callback_path:
                    # 如果已有模板且包含命名空间，不重复添加
                    if not (new_sig.emit_template and "::" in new_sig.emit_template):
                        # 添加命名空间前缀到 emit_template
                        if new_sig.emit_template and "{" in new_sig.emit_template:
                            # 已有模板，在函数名前添加命名空间
                            if symbol_name in new_sig.emit_template:
                                new_sig.emit_template = new_sig.emit_template.replace(
                                    symbol_name, f"{namespace}::{symbol_name}", 1
                                )
                            else:
                                # 模板中没有函数名，在开头添加命名空间
                                new_sig.emit_template = (
                                    f"{namespace}::{new_sig.emit_template}"
                                )
                        else:
                            # 没有模板，创建默认模板
                            new_sig.emit_template = (
                                f"{namespace}::{symbol_name}({{args}})"
                            )

                new_symbol.add_signature(new_sig)

    def build_from_ast(self, node: ast.Import | ast.ImportFrom) -> None:
        """从AST构建Import节点，提取导入的符号列表"""
        super().build_from_ast(node)

        assert self._is_module_level_import(), "import语句必须在模块级别"

        if isinstance(node, ast.ImportFrom):
            # from module import symbol1, symbol2
            self.import_kind = ImportKind.FROM_IMPORT
            # 处理相对导入：level > 0 表示相对导入
            if node.level > 0:
                # 相对导入：from .module import ... 或 from ..module import ...
                dots = "." * node.level
                self.source_module = dots + (node.module or "")
            else:
                # 绝对导入：from module import ...
                self.source_module = node.module or ""

            self.import_type = "include"

            # 提取导入的符号列表
            self.imported_symbols = []
            if node.names:
                for alias in node.names:
                    self.imported_symbols.append(alias.name)
                if not self.name:
                    self.name = "import:" + ":".join(self.imported_symbols)
            else:
                # from module import *（暂不支持）
                self.name = self.source_module

        elif isinstance(node, ast.Import):
            # import module1, module2, module3
            self.import_kind = ImportKind.IMPORT
            self.name = "import:"
            self.imported_modules = []
            for alias in node.names:
                module_name = alias.asname if alias.asname else alias.name
                self.imported_modules.append(alias.name)
                self.name += module_name + ","
                self.import_type = "include"

            # 移除末尾的逗号
            if self.name.endswith(","):
                self.name = self.name[:-1]

    def resolve_import(self, compiler: "MCPyCompiler"):
        """解析导入语句，统一通过 ModuleManager 处理所有模块"""
        if self.is_resolved:
            return

        # 保存编译器引用到扩展参数，以便子方法访问
        self.set_extension_param("compiler", compiler)

        # 使用编译器提供的模块管理器
        module_manager = compiler.get_module_manager()

        if self.import_kind == ImportKind.FROM_IMPORT:
            # from module import symbol1, symbol2
            # 对于 filter_modules（如 typing），跳过导入
            if self.source_module in filter_modules:
                self.is_resolved = True
                return

            # 解析导入路径（处理相对导入）
            resolved_path = self._resolve_import_path()

            # 通过 ModuleManager 获取模块
            ir_module = module_manager.get_module(resolved_path)
            if ir_module:
                self.resolved_modules[self.source_module] = ir_module
                ir_module.set_parent(self)
                self._import_symbols_from_module(ir_module)

                # 保存模块的命名空间信息
                current_module = self._get_current_module()
                if current_module:
                    self._save_module_namespace_info(current_module, ir_module)

        elif self.import_kind == ImportKind.IMPORT:
            # import module1, module2, module3
            for module_name in self.imported_modules:
                # 对于 filter_modules（如 typing），跳过导入
                if module_name in filter_modules:
                    continue

                # 通过 ModuleManager 获取模块（自动处理 builtin 模块）
                ir_module = module_manager.get_module(module_name)
                if ir_module:
                    self.resolved_modules[module_name] = ir_module

        self.is_resolved = True

    def _resolve_import_path(self) -> str:
        """解析导入路径，处理相对导入"""
        if not self.source_module.startswith("."):
            # 绝对导入，直接返回
            return self.source_module

        # 相对导入，需要基于当前模块路径解析
        current_module = self._get_current_module()
        if not current_module:
            raise ValueError(f"无法解析相对导入 {self.source_module}：找不到当前模块")

        # 获取当前模块的包路径
        current_package = self._get_module_package_path(current_module)

        # 处理相对导入
        dots_count = len(self.source_module) - len(self.source_module.lstrip("."))
        relative_part = self.source_module[dots_count:]

        if dots_count == 1:
            # from .module import ... -> 同级目录
            if relative_part:
                return f"{current_package}.{relative_part}"
            else:
                return current_package
        else:
            # from ..module import ... -> 上级目录
            package_parts = current_package.split(".")
            if len(package_parts) < dots_count - 1:
                raise ValueError(f"相对导入层级过深：{self.source_module}")

            parent_package = ".".join(package_parts[: -(dots_count - 1)])
            if relative_part:
                return f"{parent_package}.{relative_part}"
            else:
                return parent_package

    def _get_current_module(self) -> Optional["IRModule"]:
        """获取当前模块（import语句所在的模块）"""
        current = self.parent
        while current:
            if current.node_type == "module" and isinstance(current, IRModule):
                return current
            current = current.parent
        return None

    def _get_module_package_path(self, ir_module: IRModule) -> str:
        """获取模块的包路径"""
        # 从模块的 module_full_name 获取包路径
        module_name = ir_module.module_full_name
        assert module_name is not None, "模块名为空"

        # 如果是__init__.py文件，返回包名
        if "." in module_name:
            # 对于 mod.sub_mod，返回 mod（父包）
            return ".".join(module_name.split(".")[:-1])
        return module_name

    def _import_symbols_from_module(self, source_ir_module: "IRModule"):
        """从目标模块导入符号或子模块"""
        if not self.imported_symbols:
            return

        # 确保源模块的符号缓存已构建
        # 这很重要，因为 @mcpy_type_alias 注释扩展可能在 type_analysis 阶段才被处理
        # 如果符号缓存未构建，lookup_symbol 可能找不到通过注释扩展注册的类型别名
        if not source_ir_module._symbol_cache_built:
            source_ir_module.build_symbol_cache()

        # 为每个导入的符号创建符号引用
        for symbol_name in self.imported_symbols:
            # 先尝试作为符号查找（类、函数等）
            symbol = source_ir_module.lookup_symbol(
                symbol_name, symbol_kinds=[SymbolKind.CLASS]
            )
            if not symbol:
                symbol = source_ir_module.lookup_symbol(symbol_name)

            if symbol:
                # 找到符号，注册它
                self._register_symbol(symbol_name, symbol, source_ir_module)
            else:
                # 没有找到符号，尝试作为子模块导入
                if self._try_import_as_submodule(symbol_name, source_ir_module):
                    continue

                # 既不是符号也不是子模块，报错
                assert (
                    False
                ), f"模块 {source_ir_module.module_full_name} 中符号 {symbol_name} 不存在"

    def _register_symbol(
        self, symbol_name: str, symbol: Symbol, source_ir_module: "IRModule"
    ):
        """将符号注册到模块的符号注册表"""
        # 获取当前模块
        current_module = self._get_current_module()
        if not current_module:
            return

        # 根据符号类型进行不同的注册
        if symbol.kind == SymbolKind.CLASS:
            # 这是一个类型符号，注册为导入类型
            self._register_imported_type(
                current_module, symbol_name, symbol, source_ir_module
            )
        else:
            # 这是一个函数符号，注册为函数签名
            self._register_imported_function(
                current_module, symbol_name, symbol, source_ir_module
            )

    def _register_imported_type(
        self,
        current_module: IRModule,
        type_name: str,
        symbol: Symbol,
        source_ir_module: "IRModule",
    ):
        """注册导入的类型符号"""
        # 注册类型符号
        current_module.symbol_table.register_imported_type(type_name, symbol)

        # 复制类型配置
        if source_ir_module:
            source_config = source_ir_module.symbol_table.get_type_config(type_name)
            if source_config:
                current_module.symbol_table.register_imported_type_config(
                    type_name, source_config
                )

            # 如果源模块有命名空间，保存到符号的 type_config 中
            namespace = source_ir_module.get_extension_param("namespace")
            if namespace:
                if not symbol.type_config:
                    symbol.type_config = {}
                symbol.type_config["namespace"] = namespace

        # 导入所需的头文件
        self._import_required_headers(current_module, symbol, source_ir_module)

    def _register_imported_function(
        self,
        current_module: IRModule,
        symbol_name: str,
        symbol: Symbol,
        source_ir_module: "IRModule",
    ):
        """注册导入的函数符号"""
        # 注册符号本身（包含 type_info）
        imported_symbol = self._create_function_symbol(
            symbol_name, symbol, current_module, source_ir_module
        )
        # 使用公共接口注册函数符号
        current_module.symbol_table.register_function_symbol(imported_symbol)

        # 注册签名（包含命名空间前缀等修改）
        signature = symbol.to_signature()
        if not signature:
            return

        # 应用命名空间前缀
        self._apply_namespace_to_signature(signature, symbol_name, source_ir_module)

        # 导入所需的头文件
        self._import_required_headers(current_module, symbol, source_ir_module)

        current_module.symbol_table.register_signature(signature)

    def _create_function_symbol(
        self,
        symbol_name: str,
        symbol: Symbol,
        current_module: IRModule,
        source_ir_module: "IRModule",
    ) -> Symbol:
        """创建导入函数符号的副本"""
        return Symbol(
            name=symbol_name,
            kind=symbol.kind,
            type_info=symbol.type_info,
            module=current_module.module_full_name,
            line=symbol.line,
            column=symbol.column,
            is_imported=True,
            import_path=symbol.import_path or source_ir_module.module_full_name,
            ir_node=symbol.ir_node,
            scope_node=None,
            is_static=symbol.is_static,
            type_config=symbol.type_config,
            priority=symbol.priority,
        )

    def _import_required_headers(
        self, current_module: IRModule, symbol: Symbol, source_ir_module: "IRModule"
    ) -> None:
        """导入符号所需的头文件"""
        # 导入被导入模块的头文件
        if source_ir_module:
            for include in source_ir_module.includes:
                current_module.require_include(include)

        # 导入符号自身的头文件
        if symbol.type_config and "headers" in symbol.type_config:
            current_module.require_includes(symbol.type_config["headers"])

    def _apply_namespace_to_signature(
        self, signature: "Signature", symbol_name: str, source_ir_module: "IRModule"
    ) -> None:
        """为签名添加命名空间前缀

        Args:
            signature: 函数签名
            symbol_name: 符号名称
        """
        namespace = source_ir_module.get_extension_param("namespace")
        if not namespace:
            return

        # 如果签名已有回调，不修改 emit_template
        if signature.callback_path:
            return

        # 如果已有模板且包含命名空间，不重复添加
        if signature.emit_template and "::" in signature.emit_template:
            return

        # 添加命名空间前缀到 emit_template
        if signature.emit_template and "{" in signature.emit_template:
            # 已有模板，在函数名前添加命名空间
            if symbol_name in signature.emit_template:
                signature.emit_template = signature.emit_template.replace(
                    symbol_name, f"{namespace}::{symbol_name}", 1
                )
            else:
                # 模板中没有函数名，在开头添加命名空间
                signature.emit_template = f"{namespace}::{signature.emit_template}"
        else:
            # 没有模板，创建默认模板
            signature.emit_template = f"{namespace}::{symbol_name}({{args}})"

    def _save_module_namespace_info(
        self, current_module: IRModule, source_ir_module: "IRModule"
    ):
        """保存导入模块的命名空间信息

        Args:
            current_module: 当前模块
        """
        # 检查导入的模块是否有命名空间定义
        namespace = source_ir_module.get_extension_param("namespace")
        if namespace:
            # 保存模块名到命名空间的映射（使用扩展参数）
            imported_namespaces = current_module.get_extension_param(
                "imported_module_namespaces"
            )
            if not imported_namespaces:
                imported_namespaces = {}
                current_module.set_extension_param(
                    "imported_module_namespaces", imported_namespaces
                )

            # 从导入路径提取模块名（最后一部分）
            module_name = (
                self.source_module.split(".")[-1]
                if "." in self.source_module
                else self.source_module
            )
            imported_namespaces[module_name] = namespace

    def _try_import_as_submodule(
        self, submodule_name: str, source_ir_module: "IRModule"
    ) -> bool:
        """尝试将名称作为子模块导入

        Args:
            submodule_name: 子模块名称

        Returns:
            bool: 是否成功导入子模块
        """
        # 构建子模块的完整路径
        parent_module_path = source_ir_module.module_full_name
        submodule_path = f"{parent_module_path}.{submodule_name}"

        # 获取当前模块
        current_module = self._get_current_module()
        if not current_module:
            return False

        # 从编译器获取模块管理器
        compiler = self._get_compiler()
        if not compiler:
            return False

        module_manager = compiler.get_module_manager()

        # 尝试加载子模块
        submodule = module_manager.get_module(submodule_path)
        if not submodule:
            return False

        # 子模块加载成功，将子模块的所有符号注册到当前模块
        self._import_all_symbols_from_submodule(
            current_module, submodule, submodule_name
        )

        return True

    def _import_all_symbols_from_submodule(
        self, current_module: IRModule, submodule: IRModule, submodule_name: str
    ):
        """导入子模块的所有符号到当前模块

        Args:
            current_module: 当前模块
            submodule: 子模块
            submodule_name: 子模块名称（用于创建命名空间映射）
        """
        # 确保符号缓存已构建
        if not submodule._symbol_cache_built:
            submodule.build_symbol_cache()

        # 保存子模块的命名空间信息
        namespace = submodule.get_extension_param("namespace")
        if namespace:
            imported_namespaces = current_module.get_extension_param(
                "imported_module_namespaces"
            )
            if not imported_namespaces:
                imported_namespaces = {}
                current_module.set_extension_param(
                    "imported_module_namespaces", imported_namespaces
                )
            imported_namespaces[submodule_name] = namespace

        # 导入子模块的所有符号到当前模块的符号表
        for symbol_name, symbol in submodule._symbol_map.items():
            # 创建带有子模块前缀的符号
            prefixed_name = f"{submodule_name}.{symbol_name}"

            # 根据符号类型进行注册
            if symbol.kind == SymbolKind.CLASS:
                self._register_imported_type_with_prefix(
                    current_module, prefixed_name, symbol, submodule
                )
            else:
                self._register_imported_function_with_prefix(
                    current_module, prefixed_name, symbol, submodule
                )

        # 为子模块本身创建 MODULE 符号，使类型推导能够找到它
        if not current_module._symbol_cache_built:
            current_module.build_symbol_cache()

        current_module._symbol_map[submodule_name] = Symbol(
            name=submodule_name,
            kind=SymbolKind.MODULE,
            ir_node=self,  # 指向 IRImportNode，便于类型推导时访问 resolved_modules
            type_info=TypeInfo(kind=TypeKind.MODULE, name=submodule_name),
        )

        # 将子模块保存到 resolved_modules 中，供类型推导使用
        # 类型推导会通过 import_node.resolved_modules.get(object_name) 访问子模块
        self.resolved_modules[submodule_name] = submodule

        # 导入子模块的头文件
        for include in submodule.includes:
            current_module.require_include(include)

    def _register_imported_type_with_prefix(
        self,
        current_module: IRModule,
        prefixed_name: str,
        symbol: Symbol,
        submodule: IRModule,
    ):
        """注册带前缀的导入类型符号"""
        # 创建新符号
        new_symbol = Symbol(
            name=prefixed_name,
            kind=symbol.kind,
            type_info=symbol.type_info,
            module=current_module.module_full_name,
            line=symbol.line,
            column=symbol.column,
            is_imported=True,
            import_path=submodule.module_full_name,
            ir_node=symbol.ir_node,
            scope_node=symbol.scope_node,
            is_static=symbol.is_static,
            type_config=symbol.type_config,
            priority=symbol.priority,
            is_template_type=symbol.is_template_type,
            is_type_alias=symbol.is_type_alias,
            canonical_name=symbol.canonical_name,
        )

        # 注册类型符号
        current_module.symbol_table.register_imported_type(prefixed_name, new_symbol)

        # 复制类型配置
        source_config = submodule.symbol_table.get_type_config(symbol.name)
        if source_config:
            current_module.symbol_table.register_imported_type_config(
                prefixed_name, source_config
            )

    def _register_imported_function_with_prefix(
        self,
        current_module: IRModule,
        prefixed_name: str,
        symbol: Symbol,
        submodule: IRModule,
    ):
        """注册带前缀的导入函数符号"""
        # 创建新符号
        new_symbol = Symbol(
            name=prefixed_name,
            kind=symbol.kind,
            type_info=symbol.type_info,
            module=current_module.module_full_name,
            line=symbol.line,
            column=symbol.column,
            is_imported=True,
            import_path=submodule.module_full_name,
            ir_node=symbol.ir_node,
            scope_node=None,
            is_static=symbol.is_static,
            type_config=symbol.type_config,
            priority=symbol.priority,
        )

        # 使用公共接口注册函数符号
        current_module.symbol_table.register_function_symbol(new_symbol)
        global_registry = get_global_registry()

        for sig in symbol.signatures:
            # 先尝试从全局注册表中查找更完整的签名
            # 查找带和不带命名空间前缀的签名
            global_sig = None
            for sig_name in [
                symbol.name,
                f"{submodule.module_full_name}.{symbol.name}",
            ]:
                found_sig = global_registry.lookup_global_function(
                    sig_name, args_types=None
                )
                if found_sig and found_sig.signatures:
                    # 找到匹配的签名
                    for gs in found_sig.signatures:
                        if self._signatures_match(gs, sig):
                            global_sig = gs
                            break
                if global_sig:
                    break

            # 使用全局签名（如果找到）或原始签名
            base_sig = global_sig if global_sig else sig

            # 创建签名副本（深拷贝以保留所有属性包括 param_overrides）
            new_sig = copy.deepcopy(base_sig)
            new_sig.function_name = prefixed_name

            # 应用命名空间前缀（如果子模块有命名空间）
            namespace = submodule.get_extension_param("namespace")
            if namespace and not new_sig.callback_path:
                # 如果已有模板且包含命名空间，不重复添加
                if not (new_sig.emit_template and "::" in new_sig.emit_template):
                    # 添加命名空间前缀到 emit_template
                    if new_sig.emit_template and "{" in new_sig.emit_template:
                        # 已有模板，在函数名前添加命名空间
                        if symbol.name in new_sig.emit_template:
                            new_sig.emit_template = new_sig.emit_template.replace(
                                symbol.name, f"{namespace}::{symbol.name}", 1
                            )
                        else:
                            # 模板中没有函数名，在开头添加命名空间
                            new_sig.emit_template = (
                                f"{namespace}::{new_sig.emit_template}"
                            )
                    else:
                        # 没有模板，创建默认模板
                        new_sig.emit_template = f"{namespace}::{symbol.name}({{args}})"

            current_module.symbol_table.register_signature(new_sig)

    def _signatures_match(self, sig1, sig2) -> bool:
        """检查两个签名是否匹配（参数类型相同）"""
        if not hasattr(sig1, "param_types") or not hasattr(sig2, "param_types"):
            return False
        return sig1.param_types == sig2.param_types

    def _get_compiler(self) -> Optional["MCPyCompiler"]:
        """获取编译器实例"""
        # 从模块树向上查找编译器
        current = self
        while current:
            if hasattr(current, "get_extension_param"):
                compiler = current.get_extension_param("compiler")
                if compiler:
                    return compiler
            if hasattr(current, "parent"):
                current = current.parent
            else:
                break
        return None

    def _is_module_level_import(self) -> bool:
        """检查import是否在模块级别（直接父节点是IRModule）"""
        return (
            self.parent is not None
            and hasattr(self.parent, "node_type")
            and self.parent.node_type == "module"
        )
